package com.bub.pay.api.shiro.sessionDao;

import com.bub.pay.framework.common.entity.model.SessionModel;
import com.bub.pay.framework.common.util.IpRemote;
import com.bub.pay.framework.common.util.SpringUtil;
import com.bub.pay.framework.shiro.manager.BNWebSubjectContext;
import com.bub.pay.core.manager.user.UserCommonManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.SimpleSession;
import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.session.mgt.eis.SessionIdGenerator;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static com.bub.pay.framework.common.constant.SystemConstants.*;
import static org.apache.shiro.subject.support.DefaultSubjectContext.AUTHENTICATED_SESSION_KEY;

public class RedisSessionDAO implements SessionDAO {

    private final SessionIdGenerator sessionIdGenerator = new JavaUuidSessionIdGenerator();


    @Override
    public Serializable create(Session session) {
        ((SimpleSession) session).setId(sessionIdGenerator.generateId(session));
        HttpServletRequest httpRequest = BNWebSubjectContext.currentRequest.get();
        httpRequest.setAttribute(SESSION_KEY, session);
        return session.getId();
    }

    @Override
    public Session readSession(Serializable sessionId) throws UnknownSessionException {

        HttpServletRequest httpRequest = BNWebSubjectContext.currentRequest.get();

        SimpleSession simpleSession = (SimpleSession) httpRequest.getAttribute(SESSION_KEY);
        if (simpleSession != null) return simpleSession;
        String loginUri = httpRequest.getRequestURI();
        if (loginUri == null) loginUri = httpRequest.getServletPath();
        if (loginUri.equals("/merchant/login")) return null;

        SessionModel sessionModel = null;
        if (httpRequest != null) {
            final String authorization = httpRequest.getHeader("Authorization");
            if (authorization != null) sessionId = authorization;
            final String userId = httpRequest.getHeader("UserId");

            if (userId != null) {
                UserCommonManager userCommonManager = SpringUtil.getBean(UserCommonManager.class);
                sessionModel = userCommonManager.checkSession((String) sessionId, userId, SYS_TYPE_MERCHANT, IpRemote.getIpAddr(httpRequest));
            }
        }

        if (sessionModel != null) {
            simpleSession = new SimpleSession();
            simpleSession.setAttribute(USER_INFO, sessionModel);
            simpleSession.setId(sessionId);
            simpleSession.setAttribute(AUTHENTICATED_SESSION_KEY, true);
            List<PrincipalCollection> principalCollectionList = new ArrayList<>();
            SimplePrincipalCollection simplePrincipalCollection = new SimplePrincipalCollection(sessionModel.getLoginName(), "userRealm");

            principalCollectionList.add(simplePrincipalCollection);
            simpleSession.setAttribute(RUN_AS_PRINCIPALS_SESSION_KEY, principalCollectionList);
            httpRequest.setAttribute(SESSION_KEY, simpleSession);
            return simpleSession;
        }
        return null;
    }

    @Override
    public void update(Session session) throws UnknownSessionException {

    }

    @Override
    public void delete(Session session) {

    }

    @Override
    public Collection<Session> getActiveSessions() {
        return null;
    }
}
